package com.io.sync;

import java.io.*;
import java.nio.charset.Charset;
import java.util.Objects;

/**
 * The class/interface
 * 如果你的nexus已经配置好，并且可以单个手动上传，那么可以试试下面的批量上传！！！
 *
 * @author guod
 * @version 1.0 use jdk 1.8
 */
public class NpmDeploy {
    /**
     * 示例   我的 npm 包都在 F:\\file\\demo\\node_modules 下.
     * 我就给这个路径
     * 执行后会在我当前输入的路径后. F:\\file\\demo\\ 下生成两个txt文件.
     * successLoad.txt 为npm包上传成功的文件信息
     * errorLoad.txt 为npm包上传失败的文件信息!!
     */
    public static void main(String[] args) {
//        String files = NpmDeploy.getFiles("D:\\dev\\soft\\Webs\\node-v12.18.4-win-x64\\node_modules\\npm\\node_modules");
        String files01 = NpmDeploy.getFiles("D:\\dev\\code\\vscode-workspace\\bdi-ui\\node_modules");
//        System.out.println(files);
    }

    /**
     * 获取每一个上传的 npm 包的路径
     *
     * @param path = 根路径,比如项目文件 node_modules
     */
    public static String getFiles(String path) {
        File file = new File(path);
        int[] count = {0, 0};     //0 = 上传成功,  1= 上传失败
        if (file.isDirectory()) {
            // 获取路径下的所有文件
            File[] files = file.listFiles();
            for (int i = 0; i < Objects.requireNonNull(files).length; i++) {
                //如果还是文件夹 递归获取里面的文件 文件夹
                if (files[i].isDirectory()) {
                    System.out.println("开始上传：" + files[i].getName() + "包\t" + "目录：" + files[i].getPath());
                    //上传npm包
                    System.out.println(isPackage(files[i], count));
                } else {
                    String message = (count[1] += 1) + "\t\t\t" + files[i].getName() + "文件不是 NPM 包 , 路径：" + files[i].getPath();
                    System.out.println(message);
                    //写入错误上传信息.该路径为 node_modules 包的父级路径下\\errorLoad.txt
                    fileWrite(file, message, "errorLoad.txt");
                }
            }
        } else {
            return "路径输入错误,该路径不是node_modules集合：" + file.getPath();
        }
        return "上传完毕,成功上传" + count[0] + "个文件";
    }


    /**
     * 上传npm包
     *
     * @param file  = 当前npm包的路径,
     * @param count = 写入提示信息文件时的下标!!
     * @return = 提示信息
     */
    public static String isPackage(File file, int[] count) {
        InputStream error = null;
        File[] files = file.listFiles();
        for (int i = 0; i < Objects.requireNonNull(files).length; i++) {
            if (files[i].isFile() && files[i].getName().equals("package.json")) {
                try {
                    //执行上传npm 包的语句
                    //这里的 cmd /c F: 需要更改,你要上传的npm包在哪个盘你就改成什么
                    //比如路径在 `D` 盘, 那么改成    command.append("cmd /c D:");
                    String command = "cmd /c D:" +
                            String.format(" && cd %s", file.getPath()) +
                            //这里为自己的NPM私服路径
                            " && npm publish -registry=http://10.4.128.97:8081/repository/npm-hosted/";
                    Process p = Runtime.getRuntime().exec(command);
                    error = p.getErrorStream(); //获取执行cmd命令后的错误信息

                    BufferedReader errorReader = new BufferedReader(new InputStreamReader(error, Charset.forName("GBK")));
                    String s;
                    //输出命令执行后的提示信息
                    while ((s = errorReader.readLine()) != null) {
                        System.out.println(s);
                    }
                    errorReader.close();
                    p.waitFor();
                    if (p.exitValue() != 0) {
                        File errorFile = file.getParentFile();
                        String message = (count[1] += 1) + "\t\t\t" + file.getName() + "文件上传失败,路径:" + file.getPath();
                        fileWrite(errorFile, message, "errorLoad.txt");
                        return file.getName() + "包上传失败";
                    } else {
                        File errorFile = file.getParentFile();
                        String message = (count[0] += 1) + "\t\t\t" + file.getName() + "文件上传成功,路径:" + file.getPath();
                        fileWrite(errorFile, message, "successLoad.txt");
                        return file.getName() + "包上传成功";
                    }
                } catch (Exception e) {
                    if (error != null) {
                        try {
                            error.close();
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                    }
                    return e.getMessage();
                }
            }
        }
        File errorFile = file.getParentFile();
        String message = (count[1] += 1) + "\t\t\t" + file.getName() + "没有package.json 文件,路径:" + file.getPath();
        fileWrite(errorFile, message, "errorLoad.txt");
        return file.getName() + "上传失败,没有package.json文件";
    }


    /**
     * 文件上传成功和失败后. 写入文件存储执行信息!
     */
    private static void fileWrite(File file, String message, String fileName) {
        try {
            String path = file.getParent() + File.separator + fileName;
            File parentDir = new File(path); // null
            if (!file.exists()) {
                boolean newFile = parentDir.createNewFile();//如果txt文件不存在,那么创建
            }
            FileWriter writer = new FileWriter(parentDir, true);
            writer.write(message + System.getProperty("line.separator"));
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
